package com.mahees.portfolio.controller

import grails.validation.ValidationException;

import java.util.List;

import org.codehaus.groovy.grails.web.json.JSONArray;

import com.mahees.portfolio.domain.DevelopmentTool;
import com.mahees.portfolio.domain.SoftwareProject;
import com.mahees.portfolio.domain.SoftwareProjectTypeEnum;
import com.mahees.portfolio.service.ProjectService;

class SoftwareProjectController {
	static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

	ProjectService projectService

	def index = {
		redirect(action: "list", params: params)
	}

	def list = {
		params.max = Math.min(params.max ? params.int('max') : 10, 100)
		[softwareProjectInstanceList: SoftwareProject.list(params), softwareProjectInstanceTotal: SoftwareProject.count()]
	}

	def create = {
		def softwareProjectInstance = new SoftwareProject()
		softwareProjectInstance.properties = params
		return [softwareProjectInstance: softwareProjectInstance]
	}

	def save = { SoftwareProjectCommand cmd ->
		if (!cmd.validate()) {
			withFormat {
				json {
					render(contentType: "application/json", status: 500) {
						array {
							cmd.errors.allErrors.each { e ->
								err(field: e.field, value: e.rejectedValue, message: e.defaultMessage)
							}
						}
					}
				}
			}
			return
		}

		def hasManyOptions = [developmentTools:[]];
		cmd.developmentTools.each {
			DevelopmentTool tool = DevelopmentTool.get(it.id)
			if (tool) {
				hasManyOptions.developmentTools.add(tool);
			}
		}
		hasManyOptions.developmentTools = hasManyOptions.developmentTools.unique();

		SoftwareProject softwareProject = new SoftwareProject(
				name : cmd.name,
				description : cmd.description,
				url : cmd.url,
				projectType : cmd.projectType as SoftwareProjectTypeEnum
				)

		try {
			projectService.saveSoftwareProject(softwareProject, hasManyOptions);
			withFormat {
				json {
					render(contentType: "application/json", status: 200)
				}
			}
		}
		catch (ValidationException ex) {
		}
		catch (RuntimeException ex) {
		}
	}

	def show = {
		def softwareProjectInstance = SoftwareProject.get(params.id)
		if (!softwareProjectInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'softwareProject.label', default: 'SoftwareProject'), params.id])}"
			redirect(action: "list")
		}
		else {
			[softwareProjectInstance: softwareProjectInstance]
		}
	}

	def edit = {
		def softwareProjectInstance = SoftwareProject.get(params.id)
		if (!softwareProjectInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'softwareProject.label', default: 'SoftwareProject'), params.id])}"
			redirect(action: "list")
		}
		else {
			return [softwareProjectInstance: softwareProjectInstance]
		}
	}

	def update = {
		def softwareProjectInstance = SoftwareProject.get(params.id)
		if (softwareProjectInstance) {
			if (params.version) {
				def version = params.version.toLong()
				if (softwareProjectInstance.version > version) {

					softwareProjectInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [
						message(code: 'softwareProject.label', default: 'SoftwareProject')]
					as Object[], "Another user has updated this SoftwareProject while you were editing")
					render(view: "edit", model: [softwareProjectInstance: softwareProjectInstance])
					return
				}
			}
			softwareProjectInstance.properties = params
			if (!softwareProjectInstance.hasErrors() && softwareProjectInstance.save(flush: true)) {
				flash.message = "${message(code: 'default.updated.message', args: [message(code: 'softwareProject.label', default: 'SoftwareProject'), softwareProjectInstance.id])}"
				redirect(action: "show", id: softwareProjectInstance.id)
			}
			else {
				render(view: "edit", model: [softwareProjectInstance: softwareProjectInstance])
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'softwareProject.label', default: 'SoftwareProject'), params.id])}"
			redirect(action: "list")
		}
	}

	def delete = {
		def softwareProjectInstance = SoftwareProject.get(params.id)
		if (softwareProjectInstance) {
			try {
				softwareProjectInstance.delete(flush: true)
				flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'softwareProject.label', default: 'SoftwareProject'), params.id])}"
				redirect(action: "list")
			}
			catch (org.springframework.dao.DataIntegrityViolationException e) {
				flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'softwareProject.label', default: 'SoftwareProject'), params.id])}"
				redirect(action: "show", id: params.id)
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'softwareProject.label', default: 'SoftwareProject'), params.id])}"
			redirect(action: "list")
		}
	}
}

class SoftwareProjectCommand {

	String name
	String description
	String url
	String projectType

	JSONArray developmentTools

	static constraints = {
		name 	(nullable: false, blank: false)
		description (nullable: false, blank: false)
		url		(nullable: true, blank: true)
		projectType (nullable: false, blank: false, inList : SoftwareProjectTypeEnum.values()*.name())
	}
}